package com.ics.atable.chat.node;

import com.alibaba.cloud.ai.graph.OverAllState;
import com.alibaba.cloud.ai.graph.action.NodeAction;
import com.alibaba.fastjson.JSON;
import com.google.gson.JsonArray;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import com.google.gson.JsonParser;
import com.ics.atable.chat.cache.MultiLevelCache;
import com.ics.atable.chat.common.milvus.MilvusMultiVectorStore;
import com.ics.atable.chat.constant.VectorDatabaseConstant;
import com.ics.atable.chat.model.dto.KeyWordExtract;
import com.ics.atable.chat.model.dto.MatchedAddress;
import com.ics.atable.chat.model.dto.MatchedItem;
import com.ics.atable.chat.model.dto.RetrievalResult;
import com.ics.atable.chat.model.entity.EmbeddingsPersist;
import com.ics.atable.chat.model.entity.item.Column;
import com.ics.atable.chat.model.entity.item.Table;
import com.ics.atable.chat.model.enums.EmbeddingTypeEnum;
import com.ics.atable.chat.service.EmbeddingService;
import com.ics.atable.chat.service.EmbeddingsPersistService;
import io.milvus.v2.service.vector.request.data.BaseVector;
import io.milvus.v2.service.vector.request.data.FloatVec;
import io.milvus.v2.service.vector.response.SearchResp;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.ObjectUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.ai.embedding.Embedding;
import org.springframework.ai.embedding.EmbeddingResponse;

import java.util.*;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

import static com.ics.atable.chat.constant.VectorDatabaseConstant.ADDRESS_COLLECTION_NAME;
import static com.ics.atable.chat.constant.VectorDatabaseConstant.ITEM_COLLECTION_NAME;

/**
 * 并行检索节点
 *
 * @author haohongbin
 */
@Slf4j
public class ItemRetrievalNode implements NodeAction {

    private static final String itemCollectionName = ITEM_COLLECTION_NAME;

    private static final String addressCollectionName = ADDRESS_COLLECTION_NAME;

    private static final Integer itemTopK = 10;

    private static final Integer addressTopK = 3;

    private static final List<String> addressFields = Arrays.asList("village_name", "town_name", "county_name", "city_name", "province_name", "address_name");

    private final EmbeddingService embeddingService;

    private final EmbeddingsPersistService embeddingsPersistService;

    private final MilvusMultiVectorStore milvusMultiVectorStore;

    private final MultiLevelCache multiLevelCache;

    private static final ExecutorService executor = Executors.newFixedThreadPool(
            Runtime.getRuntime().availableProcessors() * 2,
            r -> {
                Thread t = new Thread(r, "item-retrieval-thread");
                t.setDaemon(false);
                return t;
            }
    );

    public ItemRetrievalNode(EmbeddingService embeddingService, EmbeddingsPersistService embeddingsPersistService,
                             MilvusMultiVectorStore milvusMultiVectorStore, MultiLevelCache multiLevelCache) {
        this.embeddingService = embeddingService;
        this.embeddingsPersistService = embeddingsPersistService;
        this.milvusMultiVectorStore = milvusMultiVectorStore;
        this.multiLevelCache = multiLevelCache;
    }

    @Override
    public Map<String, Object> apply(OverAllState state) throws Exception {
        log.info("parallel search node is running!!");

        // 按key和type分组存储结果
        Map<String, List<MatchedItem>> matchedItemsByKey = new HashMap<>();
        Map<String, List<MatchedAddress>> matchedAddressesByKey = new HashMap<>();

        Map<String, Object> resultMap = new HashMap<>();

        try {
            // 1. 获取待检索的指标内容
            KeyWordExtract keyWordExtract = state.value("struct_token", KeyWordExtract.class)
                    .orElseThrow(() -> new IllegalArgumentException("struct_token is missing"));

            // 1.1 获取指标列表
            List<String> items = keyWordExtract.getItems();

            List<List<String>> toMatchedItems = keyWordExtract.getItemsWithSynonyms();
//            log.info("toMatchedItems: {}", toMatchedItems);

            // 1.2 获取地址数据
            String allAddress = keyWordExtract.getAddress();
            List<String> addressList = new ArrayList<>();
            addressList.add(keyWordExtract.getVillage());
            addressList.add(keyWordExtract.getTown());
            addressList.add(keyWordExtract.getCounty());
            addressList.add(keyWordExtract.getCity());
            addressList.add(keyWordExtract.getProvince());
            addressList.add(keyWordExtract.getAddress());

            // 2. 并发执行检索
            List<CompletableFuture<Map<String, List<RetrievalResult>>>> futures = new ArrayList<>();

            // 2.1 并行检索 item
            // 2.1.1 首先做Caffeine - redis - mysql，多级检索
            // 先从 Caffeine 缓存中获取检索的答案，若没有则从 Redis 中获取，还没有则从 MySQL 中获取 embedding 向量来检索，
            // 如果没有embedding向量，则调用 embedding 接口生成，然后放到 MySQL 中
            for (int i = 0; i < toMatchedItems.size(); i++) {
                parallelRetrievalItems(toMatchedItems.get(i), futures, items.get(i));
            }

            // 2.2 检索 address
            if (StringUtils.isNotEmpty(allAddress)) {
                parallelRetrievalAddress(addressList, futures, "address");
            }

            // 3. 等待所有任务完成并收集结果
            CompletableFuture<Void> allTasks = CompletableFuture.allOf(
                    futures.toArray(new CompletableFuture[0]));
            allTasks.join();

            // 4. 收集所有结果并按key和type分组
            for (CompletableFuture<Map<String, List<RetrievalResult>>> future : futures) {
                Map<String, List<RetrievalResult>> results = future.join();
                if (results != null) {
                    for (Map.Entry<String, List<RetrievalResult>> entry : results.entrySet()) {
                        String key = entry.getKey();
                        List<RetrievalResult> resultList = entry.getValue();
                        
                        if (resultList != null) {
                            for (RetrievalResult result : resultList) {
                                if (EmbeddingTypeEnum.ITEM.getCode().equals(result.getType())) {
                                    // 转换为 MatchedItem 并按key分组
                                    MatchedItem item = (MatchedItem) result;
                                    matchedItemsByKey.computeIfAbsent(key, k -> new ArrayList<>()).add(item);
                                } else if (EmbeddingTypeEnum.ADDRESS.getCode().equals(result.getType())) {
                                    // 转换为 MatchedAddress 并按key分组
                                    MatchedAddress address = (MatchedAddress) result;
                                    matchedAddressesByKey.computeIfAbsent(key, k -> new ArrayList<>()).add(address);
                                }
//                                else {
//                                    log.info("未知的检索结果类型: {}", result.getType());
//                                }
                            }
                        }
                    }
                }
            }

//            log.info("matchedItemsByKey: {}", matchedItemsByKey);
//            log.info("matchedAddressesByKey: {}", matchedAddressesByKey);

            // 5. 对每个key的结果进行去重、排序并取top-k
            Map<String, List<MatchedItem>> topKItemsByKey = new HashMap<>();
            Map<String, List<MatchedAddress>> topKAddressesByKey = new HashMap<>();
            
            // 处理item类型结果
            for (Map.Entry<String, List<MatchedItem>> entry : matchedItemsByKey.entrySet()) {
                String key = entry.getKey();
                List<MatchedItem> itemList = entry.getValue();
                
                // 按ItemUuid去重，保留最高分
                Map<String, MatchedItem> uniqueItemsMap = new HashMap<>();
                for (MatchedItem item : itemList) {
                    uniqueItemsMap.merge(item.getItemUuid(), item,
                            (existingItem, newItem) ->
                                    existingItem.getScore() >= newItem.getScore() ? existingItem : newItem);
                }
                
                // 按分数降序排序并取top-k
                List<MatchedItem> topKItems = uniqueItemsMap.values().stream()
                        .sorted(Comparator.comparing(MatchedItem::getScore).reversed())
                        .limit(itemTopK)
                        .toList();
                
                topKItemsByKey.put(key, topKItems);
            }
            
            // 处理address类型结果
            for (Map.Entry<String, List<MatchedAddress>> entry : matchedAddressesByKey.entrySet()) {
                String key = entry.getKey();
                List<MatchedAddress> addresses = entry.getValue();
                
                // 按OrgId去重，保留最高分
                Map<String, MatchedAddress> uniqueAddressMap = new HashMap<>();
                for (MatchedAddress address : addresses) {
                    uniqueAddressMap.merge(address.getOrgId(), address,
                            (existingAddr, newAddr) ->
                                    existingAddr.getScore() >= newAddr.getScore() ? existingAddr : newAddr);
                }
                
                // 按分数降序排序并取top-k
                List<MatchedAddress> topKAddresses = uniqueAddressMap.values().stream()
                        .sorted(Comparator.comparing(MatchedAddress::getScore).reversed())
                        .limit(addressTopK)
                        .toList();
                
                topKAddressesByKey.put(key, topKAddresses);
            }


            // 6. 将按key分组的结果放入返回map
            resultMap.put("retrieved_items_by_key", topKItemsByKey);
            resultMap.put("retrieved_addresses_by_key", topKAddressesByKey);

            // 对于items，确保每个key贡献相同数量的结果
            int itemKeysCount = Math.max(1, topKItemsByKey.size());
            int itemsPerKey = Math.max(1, itemTopK / itemKeysCount);

            // 为了向后兼容，也提供扁平化的结果
            List<MatchedItem> allItems = topKItemsByKey.values().stream()
                    .flatMap(list -> list.stream().limit(itemsPerKey))
                    .sorted(Comparator.comparing(MatchedItem::getScore).reversed())
                    .limit(itemTopK)
                    .toList();
            List<MatchedAddress> allAddresses = topKAddressesByKey.values().stream()
                    .flatMap(List::stream)
                    .sorted(Comparator.comparing(MatchedAddress::getScore).reversed())
                    .limit(addressTopK)
                    .toList();
            
            resultMap.put("retrieved_items", allItems);
            resultMap.put("retrieved_addresses", allAddresses);

//            log.info("retrieval items by key: {}", topKItemsByKey);
//            log.info("retrieval addresses by key: {}", topKAddressesByKey);
            log.info("并发检索指标完成，共检索到 {} 个指标项（按key分组，已去重并取top-{})", 
                    allItems.size(), itemTopK);
            log.info("并发检索地址完成，共检索到 {} 个地址项（按key分组，已去重并取top-{})", 
                    allAddresses.size(), addressTopK);
        } catch (Exception e) {
            log.error("并行检索指标名失败：{}", e.getMessage(), e);
        }

        return resultMap;
    }


    /**
     * 并行检索地址项
     * @param addressList 待检索的地址列表
     * @param futures 用于存储检索结果的future列表
     */
    private void parallelRetrievalAddress(List<String> addressList, List<CompletableFuture<Map<String, List<RetrievalResult>>>> futures, String key) {
        // 1. 首先尝试从缓存中获取数据
        String address = addressList.get(5);
        List<RetrievalResult> cachedResults = getCachedAddress(address);


        if (CollectionUtils.isNotEmpty(cachedResults)) {
            // 2. 命中缓存，将结果添加到 future 中
            Map<String, List<RetrievalResult>> cachedResultsMap = new HashMap<>();
            cachedResultsMap.put(key, cachedResults);
            futures.add(CompletableFuture.completedFuture(cachedResultsMap));
        } else {
            // 3. 未命中缓存，进行向量检索
            log.info("未命中缓存，进行向量检索");
            // 3.1 获取 embedding
            float[] vector;
            float[] vector1 = embeddingsPersistService.getEmbeddingVectorByContent(address, EmbeddingTypeEnum.ADDRESS.getCode());
            if (vector1 == null){
                log.info("获取地址向量失败: address={}, 需要进行向量化", address);
                EmbeddingResponse embeddingResponse = embeddingService.embedding(List.of(address));
                vector = embeddingResponse.getResults().getFirst().getOutput();
                EmbeddingsPersist embeddingsPersist = new EmbeddingsPersist();
                embeddingsPersist.setContent(address);
                embeddingsPersist.setType(EmbeddingTypeEnum.ADDRESS.getCode());
                embeddingsPersist.setVector(vector);
                embeddingsPersist.setDimensions(vector.length);
                embeddingsPersistService.saveOrUpdateEmbeddingVector(embeddingsPersist);
            } else {
                vector = vector1;
            }
            // 3.2 构建查询条件
            StringBuilder filter = new StringBuilder();
            for (int i = 2; i < 5; i++) {
                if (StringUtils.isNotEmpty(addressList.get(i))){
                    filter.append(addressFields.get(i)).append(" LIKE \"").append(addressList.get(i)).append("%\"").append(" AND ");
                }
            }
//            log.info("filter: {}", filter.toString());

            // 移除最后一个" and "
            if (filter.length() > " AND ".length()) {
                filter.delete(filter.length() - " AND ".length(), filter.length());
            }

            String filterStr = filter.toString().trim();
            log.info("查询条件：{}", filterStr);

            // 3.3 检索
            CompletableFuture<Map<String, List<RetrievalResult>>> future = CompletableFuture.supplyAsync(() -> {
                        try {
                            List<BaseVector> queryVectors = List.of(new FloatVec(vector));
                            SearchResp searchResp = milvusMultiVectorStore.aVectorSearch(
                                    addressCollectionName,
                                    queryVectors,
                                    "address_name",
                                    addressTopK,
                                    filterStr
                            );

                            List<RetrievalResult> results = searchRespToAddress(searchResp);

                            // 缓存结果
                            if (CollectionUtils.isNotEmpty(results)) {
                                // 确保存储的是具体类型
                                List<MatchedAddress> concreteItems = new ArrayList<>();
                                for (RetrievalResult result : results) {
                                    if (result instanceof MatchedAddress) {
                                        concreteItems.add((MatchedAddress) result);
                                    }
                                }
                                multiLevelCache.setCache(address, "address", "atable-chat", JSON.toJSONString(concreteItems));
                            }
                            Map<String, List<RetrievalResult>> cachedAddressResults = new HashMap<>();
                            cachedAddressResults.put(key, results);
                            return cachedAddressResults;
                        } catch (Exception e) {
                            log.error("并行检索地址项失败：{}", e.getMessage(), e);
                            return new HashMap<>();
                        }
                    });
            futures.add(future);
        }
    }


    /**
     * 并行检索指标项
     * @param toMatchedItems 待检索的指标项列表
     * @param futures 用于存储检索结果的future列表
     */
    private void parallelRetrievalItems(List<String> toMatchedItems, List<CompletableFuture<Map<String, List<RetrievalResult>>>> futures, String originItem) {
        // 1. 首先尝试从缓存中获取数据
        Map<String, List<RetrievalResult>> cachedResults = getCachedItems(toMatchedItems);

        // 2. 找出未命中缓存的项目
        List<String> itemsNeedVectorSearch = new ArrayList<>();
        for (String item : toMatchedItems) {
            if (!cachedResults.containsKey(item)) {
                itemsNeedVectorSearch.add(item);
            }
        }
        log.info("缓存检索结果数量: {}", cachedResults.size());
        log.info("需要向量检索的项目数量: {}", itemsNeedVectorSearch.size());


        // 3. 对未命中缓存的项目进行向量检索
        if (CollectionUtils.isNotEmpty(itemsNeedVectorSearch)) {
            // 将需要向量检索的项目添加到future列表中
            performVectorSearchForItems(itemsNeedVectorSearch, futures, originItem);
        }

        // 4. 将缓存命中的结果也转换为future
        if (!cachedResults.isEmpty()) {
            for (Map.Entry<String, List<RetrievalResult>> entry : cachedResults.entrySet()) {
                if (entry.getValue() != null && !entry.getValue().isEmpty()) {
                    // 过滤掉null元素
                    List<RetrievalResult> filteredResults = entry.getValue().stream()
                            .filter(Objects::nonNull)
                            .collect(ArrayList::new, ArrayList::add, ArrayList::addAll);

                    Map<String, List<RetrievalResult>> filteredResultsMap = new HashMap<>();
                    filteredResultsMap.put(originItem, filteredResults);

                    if (!filteredResults.isEmpty()) {
                        CompletableFuture<Map<String, List<RetrievalResult>>> cachedFuture = CompletableFuture.completedFuture(filteredResultsMap);
                        futures.add(cachedFuture);
                    }
                }
            }
        }
        log.info("总future数量: {}", futures.size());

    }


    /**
     * 从缓存中获取已缓存的地址
     *
     * @param address 待检索的地址
     * @return 已缓存的地址映射，键为地址名称，值为地址的缓存结果列表
     */
    private List<RetrievalResult> getCachedAddress(String address) {
        List<RetrievalResult> cachedResults = new ArrayList<>();
        String cacheValue = multiLevelCache.getCache(address, "address", "atable-chat");
        if (StringUtils.isNotEmpty(cacheValue)) {
            try {
                List<MatchedAddress> addresses = JSON.parseArray(cacheValue, MatchedAddress.class);
                List<RetrievalResult> results = new ArrayList<>(addresses);
                log.info("缓存命中: address={}", address);
                cachedResults.addAll(results);
            } catch (Exception e) {
                log.warn("解析缓存结果失败: address={}", address);
                // 解析失败时，标记为需要检索
            }
        }
        return cachedResults;
    }

    /**
     * 从缓存中获取已缓存的项
     *
     * @param itemList 待检索的项列表
     * @return 已缓存的项映射，键为项名称，值为项的缓存结果列表
     */
    private Map<String, List<RetrievalResult>> getCachedItems(List<String> itemList) {
        Map<String, List<RetrievalResult>> cachedResults = new HashMap<>();

        for (String item : itemList) {
            // 1. 从caffeine，redis中获取数据
            String cacheValue = multiLevelCache.getCache(item, "item", "atable-chat");
            log.debug("处理缓存项: item={}, cacheValue={}", item, cacheValue);

            if (StringUtils.isNotEmpty(cacheValue)) {
                // 命中缓存
                try {
                    // 先尝试解析为 MatchedItem（最常见的类型）
                    List<MatchedItem> items = JSON.parseArray(cacheValue, MatchedItem.class);
                    List<RetrievalResult> results = new ArrayList<>(items);
                    log.info("缓存命中: item={}, 结果数量={}", item, results.size());
                    cachedResults.put(item, results);
                } catch (Exception e) {
                    log.warn("解析缓存结果失败: item={}, cacheValue={}", item, cacheValue, e);
                    // 解析失败时，标记为需要检索
                }
            } else {
                log.info("缓存未命中: item={}", item);
            }
        }

        return cachedResults;
    }

    /**
     * 对未命中缓存的项目进行向量检索
     * @param itemsNeedVectorSearch 未命中缓存的项目列表
     * @param futures 用于存储检索结果的future列表
     */
    private void performVectorSearchForItems(List<String> itemsNeedVectorSearch,
                                             List<CompletableFuture<Map<String, List<RetrievalResult>>>> futures,
                                             String originItem) {

        List<float[]> toMatchedItemVectors = new ArrayList<>();

        // 1. 从数据库获取已有的Embedding向量
        Map<String, float[]> itemHasEmbeddings = embeddingsPersistService.getEmbeddingVectorsByContents(
                itemsNeedVectorSearch, EmbeddingTypeEnum.ITEM.getCode());

        List<String> notNeedEmbedding = new ArrayList<>();
        List<String> itemsNeedEmbedding;

        // 2. 分离已有的向量和需要生成的向量
        for (Map.Entry<String, float[]> entry : itemHasEmbeddings.entrySet()) {
            if (entry.getValue() != null) {
                toMatchedItemVectors.add(entry.getValue());
                notNeedEmbedding.add(entry.getKey());
            }
        }

        itemsNeedEmbedding = itemsNeedVectorSearch.stream()
                .filter(item -> !notNeedEmbedding.contains(item))
                .toList();

        // 3. 为没有向量的 item 生成新的Embedding
        if (CollectionUtils.isNotEmpty(itemsNeedEmbedding)) {
            EmbeddingResponse embeddingResponse = embeddingService.embedding(itemsNeedEmbedding);
            List<EmbeddingsPersist> embeddingsPersists = new ArrayList<>(); // 需要保存到数据库的向量列表
            int i = 0;
            for (Embedding embedding : embeddingResponse.getResults()) {
                toMatchedItemVectors.add(embedding.getOutput());
                EmbeddingsPersist embeddingsPersist = new EmbeddingsPersist();
                embeddingsPersist.setContent(itemsNeedEmbedding.get(i++));
                embeddingsPersist.setVector(embedding.getOutput());
                embeddingsPersist.setType(EmbeddingTypeEnum.ITEM.getCode());
                embeddingsPersist.setDimensions(embedding.getOutput().length);
                embeddingsPersists.add(embeddingsPersist);
            }
            embeddingsPersistService.saveOrUpdateBatchEmbeddingVectors(embeddingsPersists);
        }
        log.info("不需要生成Embedding的项数量: {}", notNeedEmbedding.size());
        log.info("需要向量检索的项数量: {}", itemsNeedEmbedding.size());

        // 4. 并行检索 item
        List<String> denseFieldNames = new ArrayList<>();
        denseFieldNames.add(VectorDatabaseConstant.ItemField.ITEM_NAME.getCode());
        denseFieldNames.add(VectorDatabaseConstant.ItemField.ITEM_FATHER_NAME.getCode());
        denseFieldNames.add(VectorDatabaseConstant.ItemField.ITEM_GRANDFATHER_NAME.getCode());

        List<Float> weights = List.of(0.85f, 0.15f, 0.05f);
        String itemFilter = ""; // 过滤条件

        for (int i = 0; i < itemsNeedVectorSearch.size(); i++) {
            int finalI = i;
            String currentItem = itemsNeedVectorSearch.get(i);

            CompletableFuture<Map<String, List<RetrievalResult>>> future = CompletableFuture.supplyAsync(() -> {
                try {
                    List<BaseVector> queryVectors = List.of(
                            new FloatVec(toMatchedItemVectors.get(finalI)));
                    SearchResp searchResp = milvusMultiVectorStore.hybridSearch(
                            itemCollectionName,
                            queryVectors,
                            denseFieldNames,
                            weights,
                            itemTopK,
                            itemFilter
                    );

                    List<RetrievalResult> results = searchRespToItem(searchResp);

                    // 缓存结果
                    if (CollectionUtils.isNotEmpty(results)) {
                        // 确保存储的是具体类型 (MatchedItem)
                        List<MatchedItem> concreteItems = new ArrayList<>();
                        for (RetrievalResult result : results) {
                            if (result instanceof MatchedItem) {
                                concreteItems.add((MatchedItem) result);
                            }
                        }
                        multiLevelCache.setCache(currentItem, "item", "atable-chat", JSON.toJSONString(concreteItems));
                    }
                    Map<String, List<RetrievalResult>> cachedResults = new HashMap<>();
                    cachedResults.put(originItem, results);
                    return cachedResults;
                } catch (Exception e) {
                    log.error("检索项 {} 失败: {}", currentItem, e.getMessage(), e);
                    return new HashMap<>();
                }
            }, executor);
            futures.add(future);
        }
    }

    /**
     * 将搜索结果转换为Item对象列表
     *
     * @param searchResp 搜索结果
     * @return Item对象列表
     */
    private List<RetrievalResult> searchRespToItem(SearchResp searchResp) {
        List<RetrievalResult> matchedItems = new ArrayList<>();
        if (searchResp == null || searchResp.getSearchResults() == null) {
            return matchedItems;
        }

        for (List<SearchResp.SearchResult> searchResultList : searchResp.getSearchResults()) {
            if (searchResultList == null) continue;

            for (SearchResp.SearchResult searchResult : searchResultList) {
                if (searchResult == null) continue;

                MatchedItem matchedItem = new MatchedItem();

                // 从metadata中提取item_name和item_father_name
                Object metadataObj = searchResult.getEntity().get("metadata");
                if (ObjectUtils.isNotEmpty(metadataObj)) {
                    String metadataStr = metadataObj.toString();
                    log.info("metadata: {}", metadataStr);
                    try {
                        // 修复转义问题：尝试处理可能被转义的JSON字符串
                        String processedMetadataStr = metadataStr;

                        // 检查是否是被引号包围的JSON字符串
                        if (metadataStr.startsWith("\"{") && metadataStr.endsWith("}\"")) {
                            // 去除首尾引号并解转义
                            processedMetadataStr = metadataStr.substring(1, metadataStr.length() - 1)
                                    .replace("\\\"", "\"")
                                    .replace("\\n", "\n")
                                    .replace("\\\\", "\\");
                        }

                        JsonObject metadataJson = JsonParser.parseString(processedMetadataStr).getAsJsonObject();
                        // 设置 item_uuid
                        String itemUuid = metadataJson.has("item_uuid") ?
                                metadataJson.get("item_uuid").getAsString() : "";
                        matchedItem.setItemUuid(itemUuid);
                        // 设置 Item_full_name
                        String fullName = metadataJson.has("item_full_name") ?
                                metadataJson.get("item_full_name").getAsString() : "";
                        matchedItem.setItemFullName(fullName);

                        // 解析层级名称
                        if (StringUtils.isNotEmpty(fullName)) {
                            List<String> fullNameList = Arrays.asList(fullName.split("-"));
                            // 倒序处理fullNameList
                            Collections.reverse(fullNameList);
                            if (fullNameList.size() >= 1) {
                                matchedItem.setItemName(fullNameList.getFirst());
                            }
                            if (fullNameList.size() >= 2) {
                                matchedItem.setItemFatherName(fullNameList.get(1));
                            }
                            if (fullNameList.size() >= 3) {
                                matchedItem.setItemGrandfatherName(fullNameList.get(2));
                            }
                        }

                        // 解析 Table 和 Column
                        List<Table> tableList = new ArrayList<>();
                        if (metadataJson.has("tables") && metadataJson.get("tables").isJsonArray()) {
                            JsonArray tablesArray = metadataJson.getAsJsonArray("tables");
                            for (JsonElement tableElement : tablesArray) {
                                JsonObject tableJson = tableElement.getAsJsonObject();
                                Table table = new Table();
                                table.setTableName(tableJson.has("table_name") ?
                                        tableJson.get("table_name").getAsString() : "");
                                table.setTableUuid(tableJson.has("table_uuid") ?
                                        tableJson.get("table_uuid").getAsString() : "");

                                // 解析 columns
                                List<Column> columnList = new ArrayList<>();
                                if (tableJson.has("columns") && tableJson.get("columns").isJsonArray()) {
                                    JsonArray columnsArray = tableJson.getAsJsonArray("columns");
                                    for (JsonElement columnElement : columnsArray) {
                                        JsonObject columnJson = columnElement.getAsJsonObject();
                                        Column column = new Column();
                                        column.setColumnName(columnJson.has("name") ?
                                                columnJson.get("name").getAsString() : "");
                                        column.setColumnUuid(columnJson.has("uuid") ?
                                                columnJson.get("uuid").getAsString() : "");
                                        columnList.add(column);
                                    }
                                }
                                table.setColumnList(columnList);
                                tableList.add(table);
                            }
                        }
                        matchedItem.setTableList(tableList);
                    } catch (Exception e) {
                        log.warn("解析metadata JSON失败: {}", metadataStr, e);
                    }
                }

                matchedItem.setScore(searchResult.getScore());
                matchedItem.setType(EmbeddingTypeEnum.ITEM.getCode());
                matchedItems.add(matchedItem);
            }
        }
        return matchedItems;
    }

    /**
     * 将搜索结果转换为Address对象列表
     * @param searchResp 搜索响应
     * @return Address对象列表
     */
    private List<RetrievalResult> searchRespToAddress(SearchResp searchResp) {
        List<RetrievalResult> results = new ArrayList<>();
        for (List<SearchResp.SearchResult> searchResultList : searchResp.getSearchResults()) {
            for (SearchResp.SearchResult searchResult : searchResultList) {
                MatchedAddress matchedAddress = new MatchedAddress();
                matchedAddress.setOrgId(searchResult.getEntity().get("org_id").toString());
                Object metadataObj = searchResult.getEntity().get("metadata");
                if (metadataObj != null) {
                    String metadataStr = metadataObj.toString();

                    try {
                        String processedMetadataStr = metadataStr;

                        // 检查是否是被引号包围的JSON字符串
                        if (metadataStr.startsWith("\"{") && metadataStr.endsWith("}\"")) {
                            // 去除首尾引号并解转义
                            processedMetadataStr = metadataStr.substring(1, metadataStr.length() - 1)
                                    .replace("\\\"", "\"")
                                    .replace("\\n", "\n")
                                    .replace("\\\\", "\\");
                        }
                        JsonObject metadataJson = JsonParser.parseString(processedMetadataStr).getAsJsonObject();
                        matchedAddress.setProvince(metadataJson.has("province_name") ?
                                metadataJson.get("province_name").getAsString() : "");
                        matchedAddress.setCity(metadataJson.has("city_name") ?
                                metadataJson.get("city_name").getAsString() : "");
                        matchedAddress.setCounty(metadataJson.has("county_name") ?
                                metadataJson.get("county_name").getAsString() : "");
                        matchedAddress.setTown(metadataJson.has("town_name") ?
                                metadataJson.get("town_name").getAsString() : "");
                        matchedAddress.setVillage(metadataJson.has("village_name") ?
                                metadataJson.get("village_name").getAsString() : "");
                        matchedAddress.setAddress(metadataJson.has("address_name") ?
                                metadataJson.get("address_name").getAsString() : "");
                        matchedAddress.setScore(Double.valueOf(searchResult.getScore()));
                    } catch (Exception e) {
                        log.warn("解析metadata JSON失败: {}", metadataStr, e);
                        matchedAddress.setOrgId("");
                        matchedAddress.setProvince("");
                        matchedAddress.setCity("");
                    }
                }
                matchedAddress.setScore(searchResult.getScore());
                matchedAddress.setType(EmbeddingTypeEnum.ADDRESS.getCode());
                results.add(matchedAddress);
            }
        }
        return results;
    }

    /**
     * 解析item_list JSON数组为字符串列表
     * @param jsonArray JSON数组
     * @return 字符串列表
     */
    private List<String> parseItemList(JsonArray jsonArray) {
        List<String> itemList = new ArrayList<>();
        try {
            for (JsonElement element : jsonArray) {
                if (element.isJsonPrimitive()) {
                    itemList.add(element.getAsString());
                }
            }
        } catch (Exception e) {
            log.warn("解析item_list数组失败: {}", jsonArray, e);
        }
        return itemList;
    }

}
